package dev.ece.suit.loader.models.dae;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;

@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name="library_visual_scenes")
public class DAEVisualScenes {

	@XmlElement
	private VisualScene[] visual_scene;
	
	public VisualScene[] getVisual_scene() {
		return visual_scene;
	}

	public void setVisual_scene(VisualScene[] visual_scene) {
		this.visual_scene = visual_scene;
	}
	
	public VisualScene getVisualScene(String id) {
		if(visual_scene != null) {
			for(VisualScene visual_scene: this.visual_scene) {
				if(StringUtils.equals(id, StringUtils.join("#", visual_scene.getId()))) {
					return visual_scene;
				}
			}
		}
		return null;
	}
	
	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name="visual_scene")
	public static class VisualScene {
		
		@XmlAttribute
		private String id;
		
		@XmlAttribute
		private String name;
		
		@XmlElement
		private Node[] node;

		public Node getJointNode() {
			if(node != null) {
				for(Node node: this.node) {
					if(StringUtils.equalsIgnoreCase(DAE.JOINT, node.getType())) {
						return node;
					}
				}
			}
			return null;
		}
		
		public Node getModelNode() {
			if(node != null) {
				for(Node node: this.node) {
					if(node.getInstance_controller() != null) {
						return node;
					}
				}
			}
			return null;
		}
		
		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public Node[] getNode() {
			return node;
		}

		public void setNode(Node[] node) {
			this.node = node;
		}
		
	}
	
	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name="node")
	public static class Node {
		
		@XmlAttribute
		private String id;
		
		@XmlAttribute
		private String name;
		
		@XmlAttribute
		private String sid;
		
		@XmlAttribute
		private String type;
		
		@XmlElement
		private String matrix;
		
		@XmlElement
		private Node[] node;
		
		@XmlElement
		private InstanceController instance_controller;

		@XmlElement
		private InstanceController instance_geometry;
		
		public DAEJoint toDAEJoint(DAEJoint parent) {
			String[] array = StringUtils.split(StringUtils.trim(matrix), " ");
			float[] matrix = new float[16];
			int index = 0;
			for(int i=0; i<4; i++) {
				matrix[i] = NumberUtils.toFloat(array[index ++]);
				matrix[4 + i] = NumberUtils.toFloat(array[index ++]);
				matrix[8 + i] = NumberUtils.toFloat(array[index ++]);
				matrix[12 + i] = NumberUtils.toFloat(array[index ++]);
			}
			return new DAEJoint(this.getSid(), matrix, parent);
		}
		
		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getSid() {
			return sid;
		}

		public void setSid(String sid) {
			this.sid = sid;
		}

		public String getMatrix() {
			return matrix;
		}

		public void setMatrix(String matrix) {
			this.matrix = matrix;
		}

		public Node[] getNode() {
			return node;
		}

		public void setNode(Node[] node) {
			this.node = node;
		}

		public String getType() {
			return type;
		}

		public void setType(String type) {
			this.type = type;
		}

		public InstanceController getInstance_controller() {
			return instance_controller;
		}

		public void setInstance_controller(InstanceController instance_controller) {
			this.instance_controller = instance_controller;
		}

		public InstanceController getInstance_geometry() {
			return instance_geometry;
		}

		public void setInstance_geometry(InstanceController instance_geometry) {
			this.instance_geometry = instance_geometry;
		}
		
	}
	
	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name="instance_controller")
	public static class InstanceController  {
		
		@XmlAttribute
		private String url;
		
		@XmlElement
		private BindMaterial bind_material;

		public String getUrl() {
			return url;
		}

		public void setUrl(String url) {
			this.url = url;
		}

		public BindMaterial getBind_material() {
			return bind_material;
		}

		public void setBind_material(BindMaterial bind_material) {
			this.bind_material = bind_material;
		}
		
	}
	
	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name="bind_material")
	public static class BindMaterial {
		
		@XmlElement
		private TechniqueCommonElement technique_common;

		public TechniqueCommonElement getTechnique_common() {
			return technique_common;
		}

		public void setTechnique_common(TechniqueCommonElement technique_common) {
			this.technique_common = technique_common;
		}


	}
	
	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name="technique_common")
	public static class TechniqueCommonElement {
		
		@XmlElement
		private InstanceMaterial instance_material;

		public InstanceMaterial getInstance_material() {
			return instance_material;
		}

		public void setInstance_material(InstanceMaterial instance_material) {
			this.instance_material = instance_material;
		}
		
	}
	
	@XmlAccessorType(XmlAccessType.FIELD)
	@XmlRootElement(name="instance_material")
	public static class InstanceMaterial {
		
		@XmlAttribute
		private String symbol;
		
		@XmlAttribute
		private String target;

		public String getSymbol() {
			return symbol;
		}

		public void setSymbol(String symbol) {
			this.symbol = symbol;
		}

		public String getTarget() {
			return target;
		}

		public void setTarget(String target) {
			this.target = target;
		}
		
	}
	
}
